using System.Collections;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Media;

namespace RandomSearch.VM {
    public static class WpfControlExtensions {
        public static IEnumerable<T> FindLogicalChildsByType<T>(this DependencyObject c) where T : DependencyObject {
            if (c == null) yield return null;

            var toProcess = new Queue<DependencyObject>();
            toProcess.Enqueue(c);
            while (toProcess.Count > 0) {
                DependencyObject ctrl = toProcess.Dequeue();

                IEnumerable childs = LogicalTreeHelper.GetChildren(ctrl);

                foreach (object child in childs) {
                    var ch = child as DependencyObject;
                    if (null == ch) continue;

                    toProcess.Enqueue(ch);

                    if (ch is T)
                        yield return (T) ch;
                }
            }
        }

        public static IEnumerable<T> FindVisualChildsByType<T>(this DependencyObject c) where T : DependencyObject {
            if (c == null) yield return null;

            var toProcess = new Queue<DependencyObject>();
            toProcess.Enqueue(c);
            while (toProcess.Count > 0) {
                DependencyObject ctrl = toProcess.Dequeue();
                int n = VisualTreeHelper.GetChildrenCount(ctrl);
                for (int i = 0; i < n; i++) {
                    DependencyObject ch = VisualTreeHelper.GetChild(ctrl, i);

                    if (VisualTreeHelper.GetChildrenCount(ch) > 0)
                        toProcess.Enqueue(ch);

                    if (ch is T)
                        yield return (T) ch;
                }
            }
        }

        public static T FindVisualChildByName<T>(this DependencyObject c, string childName) where T : DependencyObject {
            if (c == null) return null;

            var toProcess = new Queue<DependencyObject>();
            toProcess.Enqueue(c);
            while (toProcess.Count > 0) {
                DependencyObject ctrl = toProcess.Dequeue();
                int n = VisualTreeHelper.GetChildrenCount(ctrl);
                for (int i = 0; i < n; i++) {
                    DependencyObject ch = VisualTreeHelper.GetChild(ctrl, i);

                    if (VisualTreeHelper.GetChildrenCount(ch) > 0)
                        toProcess.Enqueue(ch);

                    var fe = ch as FrameworkElement;
                    if (null != fe && childName == fe.Name)
                        return (T) ch;
                }
            }
            return null;
        }
    }
}